import { useRef, useEffect, useMemo, useCallback } from 'react';
import { debounce, DebouncedFunction, DebounceOptions } from '@material/helpers';

export function useDebounce<T extends (...args: any[]) => any>(
    func: T,
    wait = 300,
    options?: DebounceOptions
) {
    const latestFunc = useRef<T>(func);
    useEffect(() => {
        latestFunc.current = func;
    });

    const debouncedRef = useRef<ReturnType<typeof debounce<T>> | null>(null);

    // 用useMemo处理options，明确依赖关系
    const debounceConfig = useMemo(
        () => ({
            leading: options?.leading ?? false,
            trailing: options?.trailing ?? true,
            maxWait: options?.maxWait
        }),
        [options]
    );

    useEffect(() => {
        // 创建防抖函数，始终调用最新的函数引用
        const debouncedInstance = debounce(
            function (this: any, ...args: Parameters<T>) {
                return latestFunc.current.apply(this, args);
            },
            wait,
            debounceConfig
        );

        debouncedRef.current = debouncedInstance;

        // 清理：组件卸载或配置变化时取消防抖
        return () => {
            debouncedInstance.cancel();
        };
    }, [wait, debounceConfig]); // 仅依赖配置项，无业务依赖

    // 5. 稳定的触发函数（引用不变）
    const trigger = useCallback(
        function (this: any, ...args: Parameters<T>): ReturnType<T> | undefined {
            // 确保防抖实例已初始化，避免调用undefined
            if (debouncedRef.current) {
                return debouncedRef.current.apply(this, args);
            }
            // 初始状态降级：直接调用原始函数
            return func.apply(this, args);
        },
        [func]
    ); // 仅依赖原始函数，确保初始调用有效

    return {
        trigger: trigger as DebouncedFunction<T>
    };
}
